import { upload } from '@/services/system/image';
import { list } from '@/services/vehicle/category';
import { PlusOutlined } from '@ant-design/icons';
import {
  ModalForm,
  ProForm,
  ProFormMoney,
  ProFormSelect,
  ProFormText,
  ProFormTextArea,
} from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max';
import type { GetProp, UploadProps } from 'antd';
import { Form, Image, Upload, UploadFile } from 'antd';
import React, { useEffect, useState } from 'react';

type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];

export type UpdateFormProps = {
  onSubmit: (values: VEHICLE.Bicycle) => Promise<void>;
  editModalOpen: boolean;
  setEditModalOpen: (open: boolean) => Promise<void>;
  values: Partial<VEHICLE.Bicycle>;
};

const getBase64 = (file: FileType): Promise<string> =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result as string);
    reader.onerror = (error) => reject(error);
  });

const isNumeric = (value: any) => {
  return !isNaN(parseFloat(value)) && !isNaN(value);
};

const EditModal: React.FC<UpdateFormProps> = (props) => {
  const [previewOpen, setPreviewOpen] = useState(false);
  const [previewImage, setPreviewImage] = useState('');
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [categorieIds, setCategorieIds] = useState<number[]>([]);
  const [form] = Form.useForm<any>();
  const intl = useIntl();

  const uploadButton = (
    <button style={{ border: 0, background: 'none' }} type="button">
      <PlusOutlined />
      <div style={{ marginTop: 5 }}>Upload</div>
    </button>
  );
  const handlePreview = async (file: UploadFile) => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj as FileType);
    }

    setPreviewImage(file.url || (file.preview as string));
    setPreviewOpen(true);
  };

  const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) =>
    setFileList(newFileList);

  useEffect(() => {
    if (props.values.images) {
      let fList: UploadFile[] = [];
      props.values.images.forEach((item) => {
        fList.push({
          uid: item.id,
          name: item.fileName,
          url: item.url,
        });
      });
      setFileList(fList);
    }
    if (props.values.categories) {
      let cIds: number[] = [];
      props.values.categories.forEach((item) => {
        if (item.id) cIds.push(item.id);
      });
      setCategorieIds(cIds);
    }
    return () => {
      setFileList([]);
      setCategorieIds([]);
    };
  }, [props.values]);

  return (
    <ModalForm<VEHICLE.Bicycle>
      title={
        props.values.id
          ? intl.formatMessage({
              id: 'pages.vehicle.bicycle.createForm.editBicycle',
              defaultMessage: 'Edit Bicycle',
            })
          : intl.formatMessage({
              id: 'pages.vehicle.bicycle.createForm.newBicycle',
              defaultMessage: 'New Bicycle',
            })
      }
      open={props.editModalOpen}
      onOpenChange={(visible: boolean) => {
        props.setEditModalOpen(visible);
      }}
      form={form}
      onFinish={async (formData: any) => {
        let imageIds: any[] = [];
        const imageFormData = new FormData();
        if (fileList && fileList.length > 0) {
          fileList.forEach(async (item) => {
            if (item.originFileObj) {
              imageFormData.append('files', item.originFileObj);
            } else if (isNumeric(item.uid)) {
              imageIds.push(item.uid);
            }
          });
        }
        const response = await upload(imageFormData);
        if (response.images && response.images.length > 0) {
          response.images.forEach((item) => {
            imageIds.push(item.id);
          });
        }
        return props.onSubmit({
          ...props.values,
          ...formData,
          imageIds,
        });
      }}
      width={600}
      modalProps={{ destroyOnClose: true }}
    >
      <ProForm.Group>
        <ProFormText
          name="plateNo"
          label={intl.formatMessage({
            id: 'pages.vehicle.bicycle.plateNo',
            defaultMessage: 'plate no',
          })}
          initialValue={props.values.plateNo}
          rules={[
            {
              required: true,
              message: (
                <FormattedMessage
                  id="pages.vehicle.bicycle.plateNo.ruleName"
                  defaultMessage="plate no is required"
                />
              ),
            },
          ]}
        />
        <ProFormSelect
          name="categoryIds"
          width="sm"
          label="分类"
          initialValue={categorieIds}
          request={async () => {
            const response = await list({ current: 0, pageSize: 9999 });
            console.log(response.data);
            if (response.data && response.data.length > 0) {
              return response.data.map((item) => {
                return {
                  label: item.name,
                  value: item.id,
                };
              });
            }
            return [];
          }}
          fieldProps={{
            mode: 'multiple',
          }}
          placeholder="请选择分类"
          rules={[{ required: true, message: 'Please select category!' }]}
        />
      </ProForm.Group>
      <ProFormSelect
        name="priceType"
        label={intl.formatMessage({
          id: 'pages.vehicle.bicycle.priceType',
          defaultMessage: 'price type',
        })}
        initialValue={props.values.priceType}
        rules={[
          {
            required: true,
            message: (
              <FormattedMessage
                id="pages.vehicle.bicycle.priceType.ruleName"
                defaultMessage="price type is required"
              />
            ),
          },
        ]}
        options={[
          {
            value: '1',
            label: '一口价',
          },
          {
            value: '2',
            label: '计时',
          },
        ]}
      />
      <ProFormMoney
        name="baseFare"
        label={intl.formatMessage({
          id: 'pages.vehicle.bicycle.baseFare',
          defaultMessage: 'base fare',
        })}
        initialValue={props.values.baseFare}
        rules={[
          {
            required: true,
            message: (
              <FormattedMessage
                id="pages.vehicle.bicycle.baseFare.ruleName"
                defaultMessage="base fare is required"
              />
            ),
          },
        ]}
      />
      <ProFormMoney
        name="price"
        label={intl.formatMessage({
          id: 'pages.vehicle.bicycle.price',
          defaultMessage: 'price',
        })}
        initialValue={props.values.price}
        rules={[
          {
            required: true,
            message: (
              <FormattedMessage
                id="pages.vehicle.bicycle.price.ruleName"
                defaultMessage="price is required"
              />
            ),
          },
        ]}
      />
      <>
        <Upload
          listType="picture-card"
          fileList={fileList}
          onPreview={handlePreview}
          onChange={handleChange}
          beforeUpload={() => false}
        >
          {fileList.length >= 5 ? null : uploadButton}
        </Upload>
        {previewImage && (
          <Image
            wrapperStyle={{ display: 'none' }}
            preview={{
              visible: previewOpen,
              onVisibleChange: (visible) => setPreviewOpen(visible),
              afterOpenChange: (visible) => !visible && setPreviewImage(''),
            }}
            src={previewImage}
          />
        )}
      </>
      <ProFormTextArea
        label={intl.formatMessage({
          id: 'pages.description',
          defaultMessage: 'description',
        })}
        name="description"
      />
    </ModalForm>
  );
};

export default EditModal;
